package com.black.platform.permission.service.bz.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.black.common.annotation.DataScope;
import com.black.common.web.PageQuery;
import com.black.platform.permission.mapper.PermissionMapper;
import com.black.platform.permission.po.Permission;
import com.black.platform.permission.service.bz.PermissionService;
import com.black.common.constant.ShareConstant;
import com.black.common.vo.PermissionVo;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.jdbc.SQL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    private final JdbcTemplate jdbcTemplate;

    @Override
    public IPage<Permission> search(PageQuery<Permission> pageQuery) {
        QueryWrapper<Permission> query = new QueryWrapper<>();
        Permission queryData = pageQuery.getQueryData();
        if (!StringUtils.isEmpty(queryData.getPermissionName())) {
            query.eq("permission_name", queryData.getPermissionName());
        }
        if (!StringUtils.isEmpty(queryData.getPermissionCode())) {
            query.eq("permission_code", queryData.getPermissionCode());
        }
        if (!StringUtils.isEmpty(queryData.getPermissionType())) {
            query.eq("permission_type", queryData.getPermissionType());
        }
        if (!StringUtils.isEmpty(queryData.getSystemCode())) {
            query.eq("system_code", queryData.getSystemCode());
        }
        return this.baseMapper.selectPage(pageQuery.getPager(), query);
    }

    @Override
    public int addPermission(Permission permission) {
        return this.baseMapper.insert(permission);
    }

    @Override
    public int updatePermission(Permission permission) {
        return this.baseMapper.updateById(permission);
    }

    @Override
    public int deletePermission(Permission permission) {
        return this.baseMapper.deleteById(permission.getId());
    }

    @Override
    @DataScope(scopeType = "Permission")
    public List<Permission> getAllPermissionsBySystem(String systemCode, boolean isIncludeInvalid) {
        QueryWrapper<Permission> query = new QueryWrapper<>();
        query.eq("system_code", systemCode);
        if (!isIncludeInvalid) {
            query.eq("valid", ShareConstant.Status.VALID);
        }
        return this.baseMapper.selectList(query);
    }

    @Override
    @Cacheable(cacheNames = "UserPermission")
    public List<PermissionVo> getAllPermissionsByUser(Long userId, String systemCode, boolean isIncludeInvalid) {
        return this.baseMapper.getAllPermissionsByUser(userId, systemCode, isIncludeInvalid);
    }

    @Override
    public List<PermissionVo> getAllDataPermissionsByUser(Long userId, String systemCode) {
        SQL sql = new SQL();
        sql.SELECT("p.permission_code permissionCode,p.permission_type permissionType ")
                .FROM("permission p")
                .JOIN("role_permission rp ON p.id= rp.permission_id")
                .JOIN("position_role pr ON rp.role_id = pr.role_id")
                .JOIN("user_position up ON pr.position_id = up.position_id ")
                .WHERE("p.permission_type='data' AND up.user_id = ? AND p.system_code = ? ");
        return jdbcTemplate.query(sql.toString(), new Object[]{userId, systemCode}, new BeanPropertyRowMapper<>(PermissionVo.class));
    }


    @Override
    public List<Permission> getAllPermissionsByRoleCode(String roleCode, String systemCode, boolean isIncludeInvalid) {
        return this.baseMapper.getAllPermissionsByRoleCode(roleCode, systemCode, isIncludeInvalid);
    }
}
